package com.module.ble.ui.scanBle

import android.Manifest
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import com.alibaba.android.arouter.facade.annotation.Route
import com.common.app.base.AppActivity
import com.common.app.core.RouterHub
import com.common.app.data.bean.KeyPre
import com.common.app.helper.RouterHelper
import com.common.app.utls.HeadTitleUtils
import com.common.base.app.extras.no
import com.common.base.app.extras.otherwise
import com.common.base.app.extras.setOnClickListener
import com.common.base.app.extras.setText
import com.common.base.app.extras.setVisibility
import com.common.base.app.extras.showToast
import com.common.base.app.extras.yes
import com.common.base.listener.AlertDialogConfirmBtnListener
import com.common.base.utils.AppUtils
import com.common.base.utils.SpUtilsManagement
import com.common.base.utils.StatusBarUtils
import com.common.base.utils.ViewUtils
import com.common.base.utils.ViewUtils.initRecyclerView
import com.common.base.widget.animator.CustomAnimation1
import com.module.ble.R
import com.module.ble.data.bean.CusBleDeviceInfo
import com.module.ble.databinding.BleActivityScanBleDeviceNewBinding
import com.module.ble.listener.CusConnectBleDeviceExpandListener
import com.module.ble.utils.AizoSDKUtil

/**
 * 作者：sosou
 * <p>
 * 版本：1.0
 * <p>
 * 创建日期：2024/10/17
 * <p>
 * 描述：扫码蓝牙设备页面
 * <p>
 * 修订历史：
 */
@Route(path = RouterHub.ROUTER_BLE_SCAN_DEVICE)
class ScanBleDeviceNewActivity :
    AppActivity<BleActivityScanBleDeviceNewBinding, ScanDeviceViewModel>(),
    View.OnClickListener, CusConnectBleDeviceExpandListener {

    private val adapter by lazy { ScanBleDeviceAdapter() }

    private var connectMac: String? = null

    private lateinit var bluetoothAdapter: BluetoothAdapter
    private var isScanning = false
    // 添加 HashSet 来缓存已扫描的设备地址
    private val scannedDeviceAddresses = mutableSetOf<String>()

    private val bluetoothScanCallback = object : ScanCallback() {
        @SuppressLint("MissingPermission")
        override fun onScanResult(callbackType: Int, result: ScanResult) {
            val device = result.device
            if (device.name.isNullOrEmpty()) {
                return
            }
            if (device.address.isNullOrEmpty()) {
                return
            }

            if (!device.name.contains("BS Ring")) {
                return
            }

            /// 使用 HashSet 检查，时间复杂度 O(1)
            if (!scannedDeviceAddresses.contains(device.address)) {
                scannedDeviceAddresses.add(device.address)
                adapter.data.add(CusBleDeviceInfo(device.name, device.address))
                adapter.notifyItemInserted(adapter.data.size)
            }
        }
    }

    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        if (permissions.all { it.value }) {
            startBluetoothScan()
        } else {
//            Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
        }
    }

    private var openBleLauncherResult = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        val resultCode = result.resultCode
        if (resultCode == RESULT_OK) {
            startBluetoothScan()
        } else if (resultCode == RESULT_CANCELED) {
            Log.i(TAG, "onActivityResult Cancel")
        }
    }

    private val runnable = Runnable {
        deviceBindingFail()
    }

    override fun getViewModel() = ScanDeviceViewModel::class.java

    override fun getViewContentBinding() = BleActivityScanBleDeviceNewBinding.inflate(layoutInflater)

    override fun getPlaceholderView() = mViewBinding.mPlaceholderView

    override fun isShowToolBar(): Boolean = false
    override fun isStatusBarTranslate(): Boolean = true

    override fun initViews() {
        super.initViews()

        StatusBarUtils.setStatusBarHeight(mViewContentBinding.statusView)
        StatusBarUtils.setStatusBarForegroundColor(this, true)

        val headTitleUtils = HeadTitleUtils(this)
        headTitleUtils.setTitle("")
        headTitleUtils.setLineStyle(10)

        initRecyclerView(mViewContentBinding.hrv)
        adapter.apply {
            adapterAnimation = CustomAnimation1()
            isAnimationFirstOnly = false
            mViewContentBinding.hrv.adapter = this
            addHeaderView(layoutInflater.inflate(R.layout.base_rlv_margin_footer_tr_view25, null))
            addFooterView(layoutInflater.inflate(R.layout.base_rlv_margin_footer_tr_view150, null))
        }

        bluetoothAdapter = (getSystemService(BLUETOOTH_SERVICE) as BluetoothManager).adapter
    }

    override fun initEvents() {
        super.initEvents()

        AizoSDKUtil.addConnectBleDeviceExpandListener(this,0)

        adapter.setOnItemClickListener { _, _, position ->
            if (ViewUtils.isFastClick()) return@setOnItemClickListener //防止多次点击
            adapter.getItem(position).apply {
                showAlertDialogTwoBtn(
                    getString(R.string.cancel_btn_zh),
                    getString(R.string.ble_scan_device_binding),
                    getString(R.string.ble_scan_device_binding_title),
                    getString(R.string.ble_scan_device_binding_note, this.bleName),
                    message2="",
                    true,
                    object : AlertDialogConfirmBtnListener {
                        override fun onCancelBtnClick() {
                        }

                        override fun onConfirmBtnClick() {
                            showDialogLoading(false, "连接中。。。")
                            connecteding.no {
                                connectMac = null
                                AizoSDKUtil.connectBleAndInitDevice(bleAddress,this@apply.bleName)
                                AppUtils.postDelayed(runnable, 40000)//40s之后没完成绑定默认失败
                            }.otherwise {
                                AizoSDKUtil.handleDevice(2)
                                changeListState(false, SpUtilsManagement.getString(KeyPre.KEY_RING_MAC, ""))
                            }
                        }
                    }).run {
                }
            }
        }

        mViewContentBinding.tvSwitch.setOnClickListener(onClick = this)
    }

    override fun lazyInitData() {
        super.lazyInitData()
        requestBLEPermission()
    }

    override fun onClick(v: View?) {
        when (v) {
            mViewContentBinding.tvSwitch -> {
                isScanning.yes {
                    stopBluetoothScan()
                }.otherwise {
                    scannedDeviceAddresses.clear()
                    adapter.data.clear()
                    adapter.notifyDataSetChanged()
                    requestBLEPermission()
                }
            }
        }
    }

    override fun onDestroy() {
        AppUtils.removeCallbacks(runnable)
        stopBluetoothScan()
        openBleLauncherResult.unregister()
        requestPermissionLauncher.unregister()
        AizoSDKUtil.removeConnectBleDeviceExpandListener(this)
        super.onDestroy()
    }

    private fun changeListState(state: Boolean, changeMac: String? = null) {
        changeMac.isNullOrEmpty().no {
            adapter.data.firstOrNull { it.bleAddress == changeMac }?.let {
                it.connecteding = state
                adapter.notifyDataSetChanged()
            }
        }
    }

    @SuppressLint("MissingPermission")
    private fun startBluetoothScan() {
        if (!bluetoothAdapter.isEnabled) {//开启蓝牙
            openBleLauncherResult.launch(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
            return
        }

        mViewContentBinding.tvSwitch.isEnabled = true

        bluetoothAdapter.bluetoothLeScanner.startScan(bluetoothScanCallback)
        isScanning = true
        setText(mViewContentBinding.tvLoading, R.string.ble_scan_device_load_run)
        setText(mViewContentBinding.tvSwitch, R.string.ble_scan_device_stop)
        setVisibility(mViewContentBinding.tvLoadingBotHint, false)
    }

    @SuppressLint("MissingPermission")
    private fun stopBluetoothScan() {
        bluetoothAdapter.bluetoothLeScanner.stopScan(bluetoothScanCallback)
        isScanning = false
        setText(mViewContentBinding.tvLoading, R.string.ble_scan_device_load_stop)
        setText(mViewContentBinding.tvSwitch, R.string.ble_scan_device_again)
        setVisibility(mViewContentBinding.tvLoadingBotHint, true)
    }

    /**
     * 检查获取权限
     */
    private fun requestBLEPermission() {
        val permissions = mutableListOf(
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
        )

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            permissions.add(Manifest.permission.BLUETOOTH_SCAN)
            permissions.add(Manifest.permission.BLUETOOTH_CONNECT)
            permissions.add(Manifest.permission.BLUETOOTH_ADVERTISE)
        }

        val permissionsToRequest = permissions.filter {
            ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
        }

        if (permissionsToRequest.isEmpty()) {
            startBluetoothScan()
        } else {
            requestPermissionLauncher.launch(permissionsToRequest.toTypedArray())
        }
    }

    fun deviceBindingFail(){
        connectMac = null
        AizoSDKUtil.onDestroyRingSdk()
        dismissLoadingDialog()
        showToast(getString(R.string.ble_device_binding_fail_hint))
    }

    /**
     * 该方法在连接绑定中会偶尔执行两编，故用connectMac做锁
     */
    override fun onConnect(macStr: String?) {
//        Log.e(TAG, "onConnect:$macStr")
        connectMac.isNullOrEmpty().yes {
            connectMac = macStr
            adapter.data.firstOrNull { it.bleAddress == macStr }?.let {
                AizoSDKUtil.boundDeviceSuc(it.bleName, it.bleAddress, true)
            }
        }
    }

    override fun onConnectError(macStr: String?, throwable: Throwable?, state: Int) {
        dismissLoadingDialog()
    }

    override fun onDisconnect(macStr: String?) {
    }

    override fun onHandleDevice(type: Int, state: Boolean) {
    }

    override fun onBoundDeviceResult(macStr: String, result: Boolean) {
        result.yes {
            AppUtils.removeCallbacks(runnable)
//            changeListState(true, macStr)
            RouterHelper.finishNavigation(RouterHub.ROUTER_BIND_GUIDE).run {
                RouterHelper.navigation(RouterHub.ROUTER_BIND_COMPLETED)
            }
            dismissLoadingDialog()
            finish()
        }.otherwise {
            deviceBindingFail()
        }
    }
}